// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import '../../cr_elements/cr_button/cr_button.m.js';
import '../../cr_elements/cr_icon_button/cr_icon_button.m.js';
import '../../cr_elements/cr_icons_css.m.js';
import '../../cr_elements/cr_grid/cr_grid.js';
import '../../cr_elements/shared_vars_css.m.js';
import '../../cr_elements/shared_style_css.m.js';
import './theme_icon.js';
import '//resources/polymer/v3_0/paper-tooltip/paper-tooltip.js';

import {SkColor} from 'chrome://resources/mojo/skia/public/mojom/skcolor.mojom-webui.js';
import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';

import {assert} from '../../js/assert.m.js';
import {hexColorToSkColor, skColorToRgba} from '../../js/color_utils.js';
import {I18nBehavior} from '../../js/i18n_behavior.m.js';

import {CustomizeThemesBrowserProxyImpl} from './browser_proxy.js';
import {ChromeTheme, CustomizeThemesClientCallbackRouter, CustomizeThemesHandlerRemote, Theme, ThemeType} from './customize_themes.mojom-webui.js';

/**
 * Element that lets the user configure the autogenerated theme.
 * @polymer
 * @extends {PolymerElement}
 */
export class CustomizeThemesElement extends mixinBehaviors
([I18nBehavior], PolymerElement) {
  static get is() {
    return 'cr-customize-themes';
  }

  static get template() {
    return html`{__html_template__}`;
  }

  static get properties() {
    return {
      /**
       * An object describing the currently selected theme.
       * @type {?Theme}
       */
      selectedTheme: {
        type: Object,
        value: null,
        observer: 'onThemeChange_',
        notify: true,
      },

      /**
       * If false, confirmThemeChanges() should be called after applying a theme
       * to permanently apply the change. Otherwise, theme changes are confirmed
       * automatically.
       * @type {Boolean}
       */
      autoConfirmThemeChanges: {
        type: Boolean,
        value: false,
      },

      /** @private {!Array<!ChromeTheme>} */
      chromeThemes_: Array,
    };
  }

  constructor() {
    super();
    /** @private {CustomizeThemesHandlerRemote} */
    this.handler_ = CustomizeThemesBrowserProxyImpl.getInstance().handler();

    /** @private {CustomizeThemesClientCallbackRouter} */
    this.callbackRouter_ =
        CustomizeThemesBrowserProxyImpl.getInstance().callbackRouter();

    /** @private {?number} */
    this.setThemeListenerId_ = null;
  }

  /** @override */
  connectedCallback() {
    super.connectedCallback();
    this.handler_.initializeTheme();
    this.handler_.getChromeThemes().then(({chromeThemes}) => {
      this.chromeThemes_ = chromeThemes;
    });

    this.setThemeListenerId_ =
        this.callbackRouter_.setTheme.addListener(theme => {
          this.selectedTheme = theme;
        });
  }

  /** @override */
  disconnectedCallback() {
    this.revertThemeChanges();
    this.callbackRouter_.removeListener(assert(this.setThemeListenerId_));
    super.disconnectedCallback();
  }

  confirmThemeChanges() {
    this.handler_.confirmThemeChanges();
  }

  revertThemeChanges() {
    this.handler_.revertThemeChanges();
  }

  /**
   * @param {!Event} e
   * @private
   */
  onCustomFrameColorChange_(e) {
    this.handler_.applyAutogeneratedTheme(hexColorToSkColor(e.target.value));
    if (this.autoConfirmThemeChanges) {
      this.handler_.confirmThemeChanges();
    }
  }

  /** @private */
  onAutogeneratedThemeClick_() {
    this.$.colorPicker.click();
  }

  /** @private */
  onDefaultThemeClick_() {
    this.handler_.applyDefaultTheme();
    if (this.autoConfirmThemeChanges) {
      this.handler_.confirmThemeChanges();
    }
  }

  /**
   * @param {!Event} e
   * @private
   */
  onChromeThemeClick_(e) {
    this.handler_.applyChromeTheme(this.$.themes.itemForElement(e.target).id);
    if (this.autoConfirmThemeChanges) {
      this.handler_.confirmThemeChanges();
    }
  }

  /** @private */
  onThemeChange_() {
    if (!this.selectedTheme ||
        this.selectedTheme.type !== ThemeType.kAutogenerated) {
      return;
    }
    const rgbaFrameColor =
        skColorToRgba(this.selectedTheme.info.autogeneratedThemeColors.frame);
    const rgbaActiveTabColor = skColorToRgba(
        this.selectedTheme.info.autogeneratedThemeColors.activeTab);
    this.$.autogeneratedTheme.style.setProperty(
        '--cr-theme-icon-frame-color', rgbaFrameColor);
    this.$.autogeneratedTheme.style.setProperty(
        '--cr-theme-icon-stroke-color', rgbaFrameColor);
    this.$.autogeneratedTheme.style.setProperty(
        '--cr-theme-icon-active-tab-color', rgbaActiveTabColor);
    this.$.colorPickerIcon.style.setProperty(
        'background-color',
        skColorToRgba(
            this.selectedTheme.info.autogeneratedThemeColors.activeTabText));
  }

  /**
   * @param {!Event} e
   * @private
   */
  onUninstallThirdPartyThemeClick_(e) {
    this.handler_.applyDefaultTheme();
    this.handler_.confirmThemeChanges();
  }

  /** @private */
  onThirdPartyLinkButtonClick_() {
    CustomizeThemesBrowserProxyImpl.getInstance().open(
        `https://chrome.google.com/webstore/detail/${
            this.selectedTheme.info.thirdPartyThemeInfo.id}`);
  }

  /**
   * @param {string|number} id
   * @return {boolean}
   * @private
   */
  isThemeIconSelected_(id) {
    if (!this.selectedTheme) {
      return false;
    }
    if (id === 'autogenerated') {
      return this.selectedTheme.type === ThemeType.kAutogenerated;
    } else if (id === 'default') {
      return this.selectedTheme.type === ThemeType.kDefault;
    } else {
      return this.selectedTheme.type === ThemeType.kChrome &&
          id === this.selectedTheme.info.chromeThemeId;
    }
  }

  /**
   * @param {string|number} id
   * @return {string}
   * @private
   */
  getTabIndex_(id) {
    if (!this.selectedTheme && id === 'autogenerated') {
      return '0';
    }
    return this.isThemeIconSelected_(id) ? '0' : '-1';
  }

  /**
   * @param {string|number} id
   * @return {string}
   * @private
   */
  getThemeIconCheckedStatus_(id) {
    return this.isThemeIconSelected_(id) ? 'true' : 'false';
  }

  /**
   * @return {boolean}
   * @private
   */
  isThirdPartyTheme_() {
    return !!this.selectedTheme &&
        this.selectedTheme.type === ThemeType.kThirdParty;
  }

  /**
   * @param {SkColor} skColor
   * @return {string}
   * @private
   */
  skColorToRgba_(skColor) {
    return skColorToRgba(skColor);
  }
}

customElements.define(CustomizeThemesElement.is, CustomizeThemesElement);
